﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace SmsGui
{

    /// <summary>
    /// This class represents decoded JSON value and converts this value to 
    /// an object of a particular type. 
    /// </summary>
    class JsonNode
    {
        object obj;

        public object Object { get { return obj; } }
        public IDictionary Dictionary { get { return obj as IDictionary; } }
        public ICollection Collection { get { return obj as ICollection; } } // or IList
        public string String { get { return obj as string; } }
        public int Int { get { return Convert.ToInt32(obj); } }


        public JsonNode(object obj1)
        {
            if (obj1 as JsonNode != null)
                obj = (obj1 as JsonNode).obj;
            else
                obj = obj1;
        }

        public override bool Equals(object obj1)
        {
            if (obj1 as JsonNode != null)
            {
                return Object.Equals((obj1 as JsonNode).Object);
            }
            return Object.Equals(obj1);
        }

        public override int GetHashCode()
        {
            return Object.GetHashCode();
        }

        public JsonNode this[string key]
        {
            get
            {
                return new JsonNode(Dictionary[key]);
            }
            set
            {
                Dictionary[key] = value.obj;
            }
        }

        public JsonNode this[int key]
        {
            get
            {
                return new JsonNode(((ArrayList)obj)[key]);
            }
        }

        public IEnumerable<JsonNode> AsArray()
        {
            var retval = new List<JsonNode>();
            ((ArrayList)obj).Each((object obj1) => { retval.Add(new JsonNode(obj1)); });
            return retval;
        }

        public IDictionary<string, JsonNode> AsDictionary()
        {
            return null;
        }

        public string AsString()
        {
            return obj.ToString();
        }

        public double AsNumeric()
        {
            {
                var d = obj as double?;
                if (d != null)
                    return d.Value;
            }
            {
                var d = obj as int?;
                if (d != null)
                    return d.Value;
            }
            {
                var d = obj as float?;
                if (d != null)
                    return d.Value;
            }
            return 0.0;
        }

        internal JsonNode NodeForKey(string p)
        {
            {
                var t = obj as Hashtable;
                if (t != null)
                {
                    return new JsonNode(t[p]);
                }
            }
            return null;
            //throw new NotImplementedException();
        }

        internal JsonNode NodeAtIndex(int p)
        {
            {
                var t = obj as ArrayList;
                if (t != null)
                {
                    return new JsonNode(t[p]);
                }
            }
            return null;
        }

        internal int Count
        {
            get
            {
                {
                    var t = obj as ArrayList;
                    if (t != null)
                    {
                        return t.Count;
                    }
                }
                return 0;
            }
        }

        internal bool BooleanForKey(string p)
        {
            {
                var t = obj as Hashtable;
                if (t != null)
                {
                    return t[p] as bool? ?? false;
                }
            }
            return false;
        }

        internal string StringForKey(string p)
        {
            {
                var t = obj as Hashtable;
                if (t != null)
                {
                    return t[p] as string ?? "";
                }
            }
            return "";
        }

        internal double DoubleForKey(string p)
        {
            {
                var t = obj as Hashtable;
                if (t != null)
                {
                    return t[p] as double? ?? 0.0;
                }
            }
            return 0.0;
        }

        internal int IntegerForKey(string p)
        {
            return (int)DoubleForKey(p);
        }

        internal ArrayList ArrayForKey(string p)
        {
            var retval = new ArrayList();
            {
                var t = obj as Hashtable;
                if (t != null)
                {
                    foreach (object obj1 in t[p] as ArrayList ?? new ArrayList())
                    {
                        retval.Add(new JsonNode(obj1));
                    }
                }
            }
            return retval;
        }

        internal int ToInteger()
        {
            return (int)AsNumeric();
        }

        internal static JsonNode FromEncodedString(string encoded)
        {
            return new JsonNode(new Json().JsonDecode(encoded));
        }
    }
}
